package dev2dev.textclient.voip;

/**
 * @author jinbing.yao
 * @createTime 2023-10-14 15:26
 **/

import cn.hutool.core.util.RandomUtil;

import java.util.*;
import javax.sip.*;
import javax.sip.address.*;
import javax.sip.header.*;
import javax.sip.message.*;

public class VoipSipExample implements SipListener {

    private SipFactory sipFactory;
    private SipStack sipStack;
    private SipProvider sipProvider;
    private MessageFactory messageFactory;
    private HeaderFactory headerFactory;
    private AddressFactory addressFactory;
    private ListeningPoint listeningPoint;
    private String ip;
    private int port;

    public VoipSipExample(String ip, int port) {
        this.ip = ip;
        this.port = port;
    }

    public void init() throws Exception {
        sipFactory = SipFactory.getInstance();
        sipFactory.setPathName("gov.nist");
//        sipStack = sipFactory.createSipStack();

        Properties properties = new Properties();
        properties.setProperty("javax.sip.STACK_NAME", "SipHandler");
        properties.setProperty("javax.sip.IP_ADDRESS", "192.168.88.253");
        properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32");
        properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "SipHandler.txt");
        properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "SipHandlerDebug.log");

        sipStack = sipFactory.createSipStack(properties);

        headerFactory = sipFactory.createHeaderFactory();
        addressFactory = sipFactory.createAddressFactory();
        messageFactory = sipFactory.createMessageFactory();
        listeningPoint = sipStack.createListeningPoint(ip, port, "udp");
        sipProvider = sipStack.createSipProvider(listeningPoint);
        sipProvider.addSipListener(this);
    }

    public void processRequest(RequestEvent requestEvent) {
        // 处理收到的请求
        System.out.println("processRequest");
        System.out.println("Request:");
        System.out.println(requestEvent.getRequest());
    }

    public void processResponse(ResponseEvent responseEvent) {
        // 处理收到的响应
        System.out.println("processResponse");
        Response response = responseEvent.getResponse();
        int status = response.getStatusCode();

        if ((status >= 200) && (status < 300)) { //Success!
            System.out.println("response:");
            System.out.println(response);
            return;
        }
    }

    public void processTimeout(TimeoutEvent timeoutEvent) {
        // 处理超时事件
        System.out.println("processTimeout");
    }

    public void processIOException(IOExceptionEvent exceptionEvent) {
        // 处理I/O异常
        System.out.println("processIOException");
    }

    public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
        // 处理事务终止事件
        System.out.println("processTransactionTerminated");
    }

    public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {
        // 处理对话终止事件
        System.out.println("processDialogTerminated");
    }

    public void makeCall(String fromUser, String fromDomain, String toUser, String toDomain, byte[] message) throws Exception {
        // 创建From头部
        SipURI fromAddress = addressFactory.createSipURI(fromUser, fromDomain);
        Address fromNameAddress = addressFactory.createAddress(fromAddress);
        fromNameAddress.setDisplayName("Alice");
        FromHeader fromHeader = headerFactory.createFromHeader(fromNameAddress, "12345");

        // 创建To头部
        SipURI toAddress = addressFactory.createSipURI(toUser, toDomain);
        Address toNameAddress = addressFactory.createAddress(toAddress);
        toNameAddress.setDisplayName("Bob");
        ToHeader toHeader = headerFactory.createToHeader(toNameAddress, null);

        // 创建Call-ID头部
        CallIdHeader callIdHeader = sipProvider.getNewCallId();

        // 创建CSeq头部
        CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(1L, Request.INVITE);

        // 创建Max-Forwards头部
        MaxForwardsHeader maxForwards = headerFactory.createMaxForwardsHeader(70);

        // 创建Via头部
        ArrayList<ViaHeader> viaHeaders = new ArrayList<>();
        ViaHeader viaHeader = headerFactory.createViaHeader(ip, port, "udp", RandomUtil.randomString(12));
        viaHeaders.add(viaHeader);

        // 创建Request-URI
        SipURI requestURI = addressFactory.createSipURI(toUser, toDomain);

        // 创建请求
        Request request = messageFactory.createRequest(requestURI, Request.INVITE, callIdHeader, cSeqHeader, fromHeader, toHeader, viaHeaders, maxForwards);

        // 其他 头部补充
        Header header = this.headerFactory.createHeader("Ais-Service", "ms-supp");
        request.addHeader(header);
        Header header2 = this.headerFactory.createHeader("Ais-Msg-id", "radio-check-rq");
        request.addHeader(header2);
        // 音频内容
        ContentTypeHeader contentTypeHeader = headerFactory
                .createContentTypeHeader("application", "sdp");
        request.setContent(message, contentTypeHeader);

//        String Request = "";
//        Request = "INVITE sip:bob@domain.com SIP/2.0 \r\n";
//        Request += "Via: SIP/2.0/UDP nm;received=51.40.80.23 \r\n";
//        Request += "From: <sip:nm@nm>;tag=root \r\n";
//        Request += "To: <sip:nm2@nm2>;tag=dff4305d81b6facb \r\n";
//        Request += "Call-ID: 50000 \r\n";
//        Request += "CSeq: 42 OPTIONS \r\n";
//        Request += "Content-Type: application/sdp \r\n";
//        Request += "Content-Length: 142";
//        Request += "\r\n\r\n";

        System.out.println(request);




        // 发送请求
        sipProvider.sendRequest(request);
    }

    public void processInvite(RequestEvent requestEvent) {
        // 处理收到的INVITE请求
        System.out.println("processInvite");
    }

    public void processBye(RequestEvent requestEvent) {
        // 处理收到的BYE请求
        System.out.println("processBye");
    }

    public void processAck(RequestEvent requestEvent) {
        // 处理收到的ACK请求
        System.out.println("processAck");
    }

    public void processCancel(RequestEvent requestEvent) {
        // 处理收到的CANCEL请求
        System.out.println("processCancel");
    }

    public void processRegister(RequestEvent requestEvent) {
        // 处理收到的REGISTER请求
        System.out.println("processRegister");
    }

    public void processOptions(RequestEvent requestEvent) {
        // 处理收到的OPTIONS请求
        System.out.println("processOptions");
    }

    public static void main(String[] args) {
        try {
            VoipSipExample voipSipExample = new VoipSipExample("127.0.0.1", 5060);
            voipSipExample.init();
            /**
             * fromUser : from
             * fromDomain : 自己的ip
             *
             * toUser : to
             * toDomain : 对方ip
             *
             */
//            voipSipExample.makeCall("alice", "127.0.0.1", "bob", "192.168.1.130",);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
